package com.sh.weblogspringboot.admin.service.impl;

import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.sh.weblogspringboot.admin.service.AdminDashboardService;
import com.sh.weblogspringboot.admin.vo.dashboard.FindDashboardPVStatisticsInfoRspVO;
import com.sh.weblogspringboot.admin.vo.dashboard.FindDashboardStatisticsInfoRspVO;
import com.sh.weblogspringboot.common.constant.Constants;
import com.sh.weblogspringboot.common.domain.dos.ArticleDO;
import com.sh.weblogspringboot.common.domain.dos.ArticlePublishCountDO;
import com.sh.weblogspringboot.common.domain.dos.StatisticsArticlePVDO;
import com.sh.weblogspringboot.common.domain.mapper.ArticleMapper;
import com.sh.weblogspringboot.common.domain.mapper.CategoryMapper;
import com.sh.weblogspringboot.common.domain.mapper.StatisticsArticlePVMapper;
import com.sh.weblogspringboot.common.domain.mapper.TagMapper;
import com.sh.weblogspringboot.common.util.Response;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @author songHai
 * @Classname AdminDashboardServiceImpl
 * @Description
 * @Date 2025/4/13 12:45
 */
@Service
@Slf4j
public class AdminDashboardServiceImpl implements AdminDashboardService {
    @Autowired
    private ArticleMapper articleMapper;

    @Autowired
    private CategoryMapper categoryMapper;

    @Autowired
    private TagMapper tagMapper;

    @Autowired
    private StatisticsArticlePVMapper articlePVMapper;

    @Override
    public Response findDashboardStatistics() {
        // 查询文章总数
        Long articleTotalCount = articleMapper.selectCount(Wrappers.emptyWrapper());

        // 查询分类总数
        Long categoryTotalCount = categoryMapper.selectCount(Wrappers.emptyWrapper());

        // 查询标签总数
        Long tagTotalCount = tagMapper.selectCount(Wrappers.emptyWrapper());

        // 文章总流量量
        List<ArticleDO> articleDOList = articleMapper.selectAllReadNum();

        Long pvTotalCount = 0L;
        if (!CollectionUtils.isEmpty(articleDOList)) {
            // 所有read_num相加
            pvTotalCount = articleDOList.stream().mapToLong(ArticleDO::getReadNum).sum();
        }

        // 组装 VO类
        FindDashboardStatisticsInfoRspVO vo = FindDashboardStatisticsInfoRspVO.builder().articleTotalCount(articleTotalCount).categoryTotalCount(categoryTotalCount).tagTotalCount(tagTotalCount).pvTotalCount(pvTotalCount).build();
        return Response.success("查询成功", vo);
    }

    @Override
    public Response findDashboardPublishArticleStatistics() {
        // 当前日期
        LocalDate currDate = LocalDate.now();
        // 当前日期倒退一年的日期
        LocalDate startDate = currDate.minusYears(1);

        // 查找这一年内，每日发布的文章数量
        List<ArticlePublishCountDO> articlePublishCountDOS = articleMapper.selectDateArticlePubblishCount(startDate, currDate.plusDays(1));

        Map<LocalDate, Long> map = null;
        if (!CollectionUtils.isEmpty(articlePublishCountDOS)) {
            // DO 转 VO
            Map<LocalDate, Long> dateArticleCountMap = articlePublishCountDOS.stream().collect(Collectors.toMap(ArticlePublishCountDO::getDate, ArticlePublishCountDO::getCount));

            // 有序Map, 返回日期文章数需要以升序排序
            map = Maps.newLinkedHashMap();
            // 从上一年的今天循环到今天
            for (; startDate.isBefore(currDate) || startDate.isEqual(currDate); startDate = startDate.plusDays(1)) {
                // 以日期作为 key 从 dateArticleCountMap 中取文章发布总量
                Long count = dateArticleCountMap.get(startDate);
                // 设置到返参 Map
                map.put(startDate, Objects.isNull(count) ? 0 : count);
            }
        }
        return Response.success("查询成功", map);
    }

    @Override
    public Response findDashboardPVStatistics() {
        // 查询最近一周的 PV 访问量记录
        List<StatisticsArticlePVDO> articlePVDOS = articlePVMapper.selectLatestWeekRecords();

        Map<LocalDate, Long> pvDateCountMap = Maps.newHashMap();
        if (!CollectionUtils.isEmpty(articlePVDOS)) {
            // 转 Map, 方便后续通过日期获取 PV 访问量
            pvDateCountMap = articlePVDOS.stream().collect(Collectors.toMap(StatisticsArticlePVDO::getPvDate, StatisticsArticlePVDO::getPvCount));
        }

        FindDashboardPVStatisticsInfoRspVO vo = null;
        // 日期集合
        List<String> pvDates = Lists.newArrayList();
        List<Long> pvCounts = Lists.newArrayList();

        // 当前日期
        LocalDate currDate = LocalDate.now();
        // 一周前
        LocalDate tempDate = currDate.minusWeeks(1);
        // 从一周前开始循环
        for (; tempDate.isBefore(currDate) || tempDate.isEqual(currDate); tempDate = tempDate.plusDays(1)) {
            // 设置对应日期的PV访问量
            pvDates.add(tempDate.format(Constants.MONTH_DAY_FORMATTER));
            pvCounts.add(Objects.isNull(pvDateCountMap.get(tempDate)) ? 0 : pvDateCountMap.get(tempDate));
        }

        vo = FindDashboardPVStatisticsInfoRspVO.builder()
                .pvDates(pvDates)
                .pvCounts(pvCounts)
                .build();

        return Response.success("查询成功", vo);
    }
}
